<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow: flow::perf::Checkpointing_timer Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow<span id="projectnumber">&#160;2.0.0</span>
   </div>
   <div id="projectbrief">Flow project: Public API.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceflow.html">flow</a></li><li class="navelem"><a class="el" href="namespaceflow_1_1perf.html">perf</a></li><li class="navelem"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#nested-classes">Classes</a> &#124;
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pub-static-methods">Static Public Member Functions</a> &#124;
<a href="#pub-attribs">Public Attributes</a> &#124;
<a href="#related">Related Functions</a> &#124;
<a href="classflow_1_1perf_1_1Checkpointing__timer-members.html">List of all members</a>  </div>
  <div class="headertitle"><div class="title">flow::perf::Checkpointing_timer Class Reference</div></div>
</div><!--header-->
<div class="contents">

<p>The central class in the <code>perf</code> Flow module, this efficiently times the user's operation, with a specified subset of timing methods; and with the optional ability to time intermediate <em>checkpoints</em> within the overall operation.  
 <a href="classflow_1_1perf_1_1Checkpointing__timer.html#details">More...</a></p>

<p><code>#include &lt;checkpt_timer.hpp&gt;</code></p>
<div class="dynheader">
Inheritance diagram for flow::perf::Checkpointing_timer:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1perf_1_1Checkpointing__timer__inherit__graph.svg" width="170" height="119"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<div class="dynheader">
Collaboration diagram for flow::perf::Checkpointing_timer:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1perf_1_1Checkpointing__timer__coll__graph.svg" width="170" height="119"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
Classes</h2></td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html">Aggregator</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This companion/inner class of <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a> provides aggregation of results from many <code><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a></code>s each measuring some user operation being repeated many times; particularly when the operation consists of multiple steps (checkpoints) of interest.  <a href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structflow_1_1perf_1_1Checkpointing__timer_1_1Checkpoint.html">Checkpoint</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">The entirety of the information recorded with each <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">Checkpointing_timer::checkpoint()</a> call; it contains the <code>Duration</code> values (for each <code>Clock_type</code>) with the time elapsed since either the preceding <code>T.checkpoint()</code> or construction.  <a href="structflow_1_1perf_1_1Checkpointing__timer_1_1Checkpoint.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:aa9940d8e87883f9985ba18939f833db9"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#aa9940d8e87883f9985ba18939f833db9">Checkpointing_timer</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, std::string &amp;&amp;name_moved, <a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601">Clock_types_subset</a> which_clocks, size_t max_n_checkpoints)</td></tr>
<tr class="memdesc:aa9940d8e87883f9985ba18939f833db9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs a new timer and immediately begins measuring time, in that the next <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> call will record the time passed since right now.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#aa9940d8e87883f9985ba18939f833db9">More...</a><br /></td></tr>
<tr class="separator:aa9940d8e87883f9985ba18939f833db9"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a886e2150b2918df43c53d4850205e1c8"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a886e2150b2918df43c53d4850205e1c8">Checkpointing_timer</a> (const <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a> &amp;src)=default</td></tr>
<tr class="memdesc:a886e2150b2918df43c53d4850205e1c8"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs a timer that is identical to but entirely independent of the source object.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#a886e2150b2918df43c53d4850205e1c8">More...</a><br /></td></tr>
<tr class="separator:a886e2150b2918df43c53d4850205e1c8"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a1d1506c1a9d63fb8f9856a1ce6a2f422"><td class="memItemLeft" align="right" valign="top"><a id="a1d1506c1a9d63fb8f9856a1ce6a2f422" name="a1d1506c1a9d63fb8f9856a1ce6a2f422"></a>
&#160;</td><td class="memItemRight" valign="bottom"><b>Checkpointing_timer</b> (<a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a> &amp;&amp;)=delete</td></tr>
<tr class="memdesc:a1d1506c1a9d63fb8f9856a1ce6a2f422"><td class="mdescLeft">&#160;</td><td class="mdescRight">For now at least there's no reason for move-construction. <br /></td></tr>
<tr class="separator:a1d1506c1a9d63fb8f9856a1ce6a2f422"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ac8c6a294890c7b59b79555c8116be552"><td class="memItemLeft" align="right" valign="top"><a id="ac8c6a294890c7b59b79555c8116be552" name="ac8c6a294890c7b59b79555c8116be552"></a>
void&#160;</td><td class="memItemRight" valign="bottom"><b>operator=</b> (const <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a> &amp;)=delete</td></tr>
<tr class="memdesc:ac8c6a294890c7b59b79555c8116be552"><td class="mdescLeft">&#160;</td><td class="mdescRight">Disallow overwriting. Copy-construction exists for a specific pattern to be possible; no need for this so far. <br /></td></tr>
<tr class="separator:ac8c6a294890c7b59b79555c8116be552"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a4c26ee75e58df6abc3b59083f920897c"><td class="memItemLeft" align="right" valign="top"><a id="a4c26ee75e58df6abc3b59083f920897c" name="a4c26ee75e58df6abc3b59083f920897c"></a>
void&#160;</td><td class="memItemRight" valign="bottom"><b>operator=</b> (<a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a> &amp;&amp;)=delete</td></tr>
<tr class="memdesc:a4c26ee75e58df6abc3b59083f920897c"><td class="mdescLeft">&#160;</td><td class="mdescRight">No copy assignment; no move assignment either. <br /></td></tr>
<tr class="separator:a4c26ee75e58df6abc3b59083f920897c"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9e6078df059d5626ab5774f0a33fbad7"><td class="memItemLeft" align="right" valign="top">const <a class="el" href="structflow_1_1perf_1_1Checkpointing__timer_1_1Checkpoint.html">Checkpoint</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7">checkpoint</a> (std::string &amp;&amp;name_moved)</td></tr>
<tr class="memdesc:a9e6078df059d5626ab5774f0a33fbad7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Records a checkpoint, which takes a sample of all enabled <code>Clock_type</code>s' clocks and records the corresponding duration(s) since the last <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> or (if none) since construction.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7">More...</a><br /></td></tr>
<tr class="separator:a9e6078df059d5626ab5774f0a33fbad7"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:afeb1faa0e4962dacf9b6a134191a4933"><td class="memItemLeft" align="right" valign="top"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#afeb1faa0e4962dacf9b6a134191a4933">since_start</a> () const</td></tr>
<tr class="memdesc:afeb1faa0e4962dacf9b6a134191a4933"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the duration(s) (for all enabled <code>Clock_type</code>s) between construction and the last <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> call.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#afeb1faa0e4962dacf9b6a134191a4933">More...</a><br /></td></tr>
<tr class="separator:afeb1faa0e4962dacf9b6a134191a4933"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a1f03d654924a3724e1f051c119f3767b"><td class="memItemLeft" align="right" valign="top">const std::vector&lt; <a class="el" href="structflow_1_1perf_1_1Checkpointing__timer_1_1Checkpoint.html">Checkpoint</a> &gt; &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a1f03d654924a3724e1f051c119f3767b">checkpoints</a> () const</td></tr>
<tr class="memdesc:a1f03d654924a3724e1f051c119f3767b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the checkpoints recorded so far.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#a1f03d654924a3724e1f051c119f3767b">More...</a><br /></td></tr>
<tr class="separator:a1f03d654924a3724e1f051c119f3767b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a378be385d0c3dda261c8944551280010"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a378be385d0c3dda261c8944551280010">scale</a> (uint64_t mult_scale, uint64_t div_scale)</td></tr>
<tr class="memdesc:a378be385d0c3dda261c8944551280010"><td class="mdescLeft">&#160;</td><td class="mdescRight">Called anytime after the last <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a>, this modifies the data collected so far to be as if every checkpoint duration D shortened/lengthened by <code>mult_scale</code> and divided by <code>div_scale</code>.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#a378be385d0c3dda261c8944551280010">More...</a><br /></td></tr>
<tr class="separator:a378be385d0c3dda261c8944551280010"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3b73f2812c2bf6a27ef2becc13859d73"><td class="memItemLeft" align="right" valign="top"><a class="el" href="structflow_1_1perf_1_1Time__pt__set.html">Time_pt_set</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a3b73f2812c2bf6a27ef2becc13859d73">now</a> () const</td></tr>
<tr class="memdesc:a3b73f2812c2bf6a27ef2becc13859d73"><td class="mdescLeft">&#160;</td><td class="mdescRight">Sample all currently enabled <code>Clock_type</code>s' clocks and return those values, each of which is a time stamp relative to some Epoch value.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#a3b73f2812c2bf6a27ef2becc13859d73">More...</a><br /></td></tr>
<tr class="separator:a3b73f2812c2bf6a27ef2becc13859d73"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a07204b9119b94bc10d53a8ba15c44797"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a07204b9119b94bc10d53a8ba15c44797">output</a> (std::ostream *os) const</td></tr>
<tr class="memdesc:a07204b9119b94bc10d53a8ba15c44797"><td class="mdescLeft">&#160;</td><td class="mdescRight">Equivalent to <code>(*os) &lt;&lt; (*this)</code>.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#a07204b9119b94bc10d53a8ba15c44797">More...</a><br /></td></tr>
<tr class="separator:a07204b9119b94bc10d53a8ba15c44797"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="inherit_header pub_methods_classflow_1_1log_1_1Log__context"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_classflow_1_1log_1_1Log__context')"><img src="closed.png" alt="-"/>&#160;Public Member Functions inherited from <a class="el" href="classflow_1_1log_1_1Log__context.html">flow::log::Log_context</a></td></tr>
<tr class="memitem:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#ae7100d2dd130d8f130e3e64fdb1f4fd9">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *logger=0)</td></tr>
<tr class="memdesc:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs <a class="el" href="classflow_1_1log_1_1Log__context.html" title="Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...">Log_context</a> by storing the given pointer to a <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> and a null <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a>.  <a href="classflow_1_1log_1_1Log__context.html#ae7100d2dd130d8f130e3e64fdb1f4fd9">More...</a><br /></td></tr>
<tr class="separator:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memTemplParams" colspan="2">template&lt;typename Component_payload &gt; </td></tr>
<tr class="memitem:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memTemplItemLeft" align="right" valign="top">&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#af1ac7f30ab442c3c6aa6079335df6c9a">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *logger, Component_payload component_payload)</td></tr>
<tr class="memdesc:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs <a class="el" href="classflow_1_1log_1_1Log__context.html" title="Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...">Log_context</a> by storing the given pointer to a <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> and a new <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> storing the specified generically typed payload (an <code>enum</code> value).  <a href="classflow_1_1log_1_1Log__context.html#af1ac7f30ab442c3c6aa6079335df6c9a">More...</a><br /></td></tr>
<tr class="separator:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a5c57a7f44959a01ca9a1c948a6686cc0">Log_context</a> (const <a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;src)</td></tr>
<tr class="memdesc:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy constructor that stores equal <code>Logger*</code> and <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> values as the source.  <a href="classflow_1_1log_1_1Log__context.html#a5c57a7f44959a01ca9a1c948a6686cc0">More...</a><br /></td></tr>
<tr class="separator:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a3d4e624833d96bdafa1485ffff472509">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move constructor that makes this equal to <code>src</code>, while the latter becomes as-if default-constructed.  <a href="classflow_1_1log_1_1Log__context.html#a3d4e624833d96bdafa1485ffff472509">More...</a><br /></td></tr>
<tr class="separator:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a5d628315d5a93908d47a281980d3113e">operator=</a> (const <a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;src)</td></tr>
<tr class="memdesc:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Assignment operator that behaves similarly to the copy constructor.  <a href="classflow_1_1log_1_1Log__context.html#a5d628315d5a93908d47a281980d3113e">More...</a><br /></td></tr>
<tr class="separator:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#aae857197aecba8606c32296bc7bec308">operator=</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move assignment operator that behaves similarly to the move constructor.  <a href="classflow_1_1log_1_1Log__context.html#aae857197aecba8606c32296bc7bec308">More...</a><br /></td></tr>
<tr class="separator:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#aa6bb8e4250586425631ef80063caf155">swap</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;other)</td></tr>
<tr class="memdesc:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Swaps <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> pointers and <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> objects held by <code>*this</code> and <code>other</code>.  <a href="classflow_1_1log_1_1Log__context.html#aa6bb8e4250586425631ef80063caf155">More...</a><br /></td></tr>
<tr class="separator:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#af4db395042b065b00398cd59845dcb4d">get_logger</a> () const</td></tr>
<tr class="memdesc:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the stored <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> pointer, particularly as many <code>FLOW_LOG_*()</code> macros expect.  <a href="classflow_1_1log_1_1Log__context.html#af4db395042b065b00398cd59845dcb4d">More...</a><br /></td></tr>
<tr class="separator:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">const <a class="el" href="classflow_1_1log_1_1Component.html">Component</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a8a5fef42dc2cedf3c0d1a6e83beb2948">get_log_component</a> () const</td></tr>
<tr class="memdesc:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns reference to the stored <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> object, particularly as many <code>FLOW_LOG_*()</code> macros expect.  <a href="classflow_1_1log_1_1Log__context.html#a8a5fef42dc2cedf3c0d1a6e83beb2948">More...</a><br /></td></tr>
<tr class="separator:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-static-methods" name="pub-static-methods"></a>
Static Public Member Functions</h2></td></tr>
<tr class="memitem:a959a0446aa6a0b6db59e9892d8f0a699"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601">Clock_types_subset</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a959a0446aa6a0b6db59e9892d8f0a699">real_clock_types</a> ()</td></tr>
<tr class="memdesc:a959a0446aa6a0b6db59e9892d8f0a699"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the bit-set containing only those <code>Clock_type</code>s enabled that measure passage of real (wall clock) time.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#a959a0446aa6a0b6db59e9892d8f0a699">More...</a><br /></td></tr>
<tr class="separator:a959a0446aa6a0b6db59e9892d8f0a699"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a32ed9864d46708789d7418ab637ff382"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601">Clock_types_subset</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a32ed9864d46708789d7418ab637ff382">process_cpu_clock_types</a> ()</td></tr>
<tr class="memdesc:a32ed9864d46708789d7418ab637ff382"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the bit-set containing only those <code>Clock_type</code>s enabled that measure passage of processor time by all threads of the calling process combined.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#a32ed9864d46708789d7418ab637ff382">More...</a><br /></td></tr>
<tr class="separator:a32ed9864d46708789d7418ab637ff382"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aabebe01d0d5096618a8a7c2cf52320fb"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601">Clock_types_subset</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#aabebe01d0d5096618a8a7c2cf52320fb">thread_cpu_clock_types</a> ()</td></tr>
<tr class="memdesc:aabebe01d0d5096618a8a7c2cf52320fb"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the bit-set containing only those <code>Clock_type</code>s enabled that measure passage of processor time by the calling thread.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#aabebe01d0d5096618a8a7c2cf52320fb">More...</a><br /></td></tr>
<tr class="separator:aabebe01d0d5096618a8a7c2cf52320fb"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3138f716f6f5b3973a5ed53f68a3c332"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="namespaceflow_1_1perf.html#ace5f154155a7d9d5c112c1a83aa04fb5">Time_pt</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a3138f716f6f5b3973a5ed53f68a3c332">now</a> (<a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">Clock_type</a> clock_type)</td></tr>
<tr class="memdesc:a3138f716f6f5b3973a5ed53f68a3c332"><td class="mdescLeft">&#160;</td><td class="mdescRight">Based on the passed in <code>clock_type</code> argument, the current time is returned for that one particular clock type.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#a3138f716f6f5b3973a5ed53f68a3c332">More...</a><br /></td></tr>
<tr class="separator:a3138f716f6f5b3973a5ed53f68a3c332"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a019df7b02e8aed1e86002c8a7b40dcf7"><td class="memItemLeft" align="right" valign="top">static <a class="el" href="structflow_1_1perf_1_1Time__pt__set.html">Time_pt_set</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a019df7b02e8aed1e86002c8a7b40dcf7">now</a> (const <a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601">Clock_types_subset</a> &amp;which_clocks)</td></tr>
<tr class="memdesc:a019df7b02e8aed1e86002c8a7b40dcf7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Based on the passed in <code>which_clocks</code> argument, the current time is returned for the clock types enabled by it.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#a019df7b02e8aed1e86002c8a7b40dcf7">More...</a><br /></td></tr>
<tr class="separator:a019df7b02e8aed1e86002c8a7b40dcf7"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-attribs" name="pub-attribs"></a>
Public Attributes</h2></td></tr>
<tr class="memitem:a25981d44a91e1315bd92711d6e18a91b"><td class="memItemLeft" align="right" valign="top"><a id="a25981d44a91e1315bd92711d6e18a91b" name="a25981d44a91e1315bd92711d6e18a91b"></a>
const std::string&#160;</td><td class="memItemRight" valign="bottom"><b>m_name</b></td></tr>
<tr class="memdesc:a25981d44a91e1315bd92711d6e18a91b"><td class="mdescLeft">&#160;</td><td class="mdescRight">The immutable human-readable name for this timer. It's <code>const</code> so no need for accessor for now. <br /></td></tr>
<tr class="separator:a25981d44a91e1315bd92711d6e18a91b"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="related" name="related"></a>
Related Functions</h2></td></tr>
<tr><td class="ititle" colspan="2"><p >(Note that these are not member functions.) </p>
</td></tr>
<tr class="memitem:a6d5b7cbbe0ec5133299f97148ef3eaa0"><td class="memItemLeft" align="right" valign="top">std::ostream &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a6d5b7cbbe0ec5133299f97148ef3eaa0">operator&lt;&lt;</a> (std::ostream &amp;os, const <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a> &amp;timer)</td></tr>
<tr class="memdesc:a6d5b7cbbe0ec5133299f97148ef3eaa0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Prints string representation of the given <code><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a></code> (whether with original data or an aggregated-result timer) to the given <code>ostream</code>.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#a6d5b7cbbe0ec5133299f97148ef3eaa0">More...</a><br /></td></tr>
<tr class="separator:a6d5b7cbbe0ec5133299f97148ef3eaa0"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >The central class in the <code>perf</code> Flow module, this efficiently times the user's operation, with a specified subset of timing methods; and with the optional ability to time intermediate <em>checkpoints</em> within the overall operation. </p>
<h3>How to use</h3>
<p >To use this: Construct a <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a>; perform the operation in question; then access results via accessors; including in particular the string/stream output operation that lays out results in human-friendly fashion. Optionally, call <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> to mark down intermediate timing results, so that the operation can be broken down into its component parts (the string/stream output will include these). This is optional, except that at least 1 checkpoint is required: the last checkpoint represents the end of the measured operation.</p>
<p >The actual measurements are performed by sampling a time stamp from <em>each</em> of N clocks, where N &lt;= M, and M is the number of values in <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a> <code>enum</code>. The N clocks are specified at construction by user; thus can measure just 1, in particular, as is often desired. This is a critical and potentially subtle decision; see doc headers of each <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a> member for tips.</p>
<h3>Performance</h3>
<p >This is a performance-measuring facility, and the performance of a performance-measuring-thing is quite important, especially since some of the things being timed can be very quick (single-digit microseconds potentially).</p>
<p >Extreme care has been taken to keep the computational fat of all the book-keeping in the class very low (and empirical testing shows this was successful). In the cases where user cooperation is necessary to avoid undoing this, the doc headers point it out. Please read docs carefully to avoid timing-technique traps that might lead to wrong conclusions and frustration.</p>
<h3>Thread safety</h3>
<p ><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a> itself is not thread-safe for non-<code>const</code> access to an object while any other access occurs concurrently. (Internally, there is no locking.) However, the nature of how one uses a timer object is that one does stuff to be measured, <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a>, more stuff, <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a>, ..., final <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a>. In other words, by its very nature, it expects only sequential non-<code>const</code> calls while measuring times &ndash; so thread safety should not come up. (However, thread safety enters the picture with <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html" title="This companion/inner class of Checkpointing_timer provides aggregation of results from many Checkpoin...">Checkpointing_timer::Aggregator</a>; see below.)</p>
<h2>Aggregation </h2>
<p ><code>Duration</code> result <em>aggregation</em> is the common-sense idea that to accurately measure the typical length of operation X is to repeat X many times (N times) and then view a sum-over-N-samples and/or mean-over-N-samples and/or mean-over-N-samples-scaled-times-M, where M is usually some convenience constant like 1,000,000. There are two patterns we provide/suggest to accomplish aggregation.</p>
<h3>Lowest-overhead aggregation approach: Single <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a></h3>
<p >Suppose you have operation X and are <em>not</em> interested in subdividing it into checkpoints; you only care about the total duration(s) (according to which <code>Clock_type</code>s interest you). Then the following technique leads to the lowest possible overhead:</p>
<div class="fragment"><div class="line"><a class="code hl_class" href="classflow_1_1perf_1_1Checkpointing__timer.html">flow::perf::Checkpointing_timer</a> sum_timer(logger, <span class="stringliteral">&quot;op name&quot;</span>, which_clocks, 1); <span class="comment">// 1 checkpoint only.</span></div>
<div class="line"><span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n_samples = 1000000;</div>
<div class="line"><span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> sample_idx = 0; sample_idx != n_samples; ++sample_idx)</div>
<div class="line">{</div>
<div class="line">  <span class="comment">// ...Operation X being measured goes here.</span></div>
<div class="line">}</div>
<div class="line">sum_timer.checkpoint(<span class="stringliteral">&quot;total&quot;</span>); <span class="comment">// Mark down the total time taken.</span></div>
<div class="line"><span class="comment">// Log the total duration(s), one per clock type!</span></div>
<div class="line"><a class="code hl_function" href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html#abd543abbfae859ddc111741468f95125">flow::perf::Checkpointing_timer::Aggregator::log_aggregated_result_in_timer</a>(sum_timer, n_samples, <span class="keyword">false</span>);</div>
<div class="line"><span class="comment">// And/or: Log mean duration(s), times N_SAMPLES_SCALE_CONVENIENCE, one per clock type!</span></div>
<div class="line">{</div>
<div class="line">  <span class="comment">// Just make a copy of the raw sum, then scale it x N_SAMPLES_SCALE_CONVENIENCE / n_samples.</span></div>
<div class="line">  <span class="keyword">auto</span> mean_scaled_timer(sum_timer);</div>
<div class="line">  mean_scaled_timer.scale(N_SAMPLES_SCALE_CONVENIENCE, n_samples);</div>
<div class="line">  <a class="code hl_function" href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html#abd543abbfae859ddc111741468f95125">flow::perf::Checkpointing_timer::Aggregator::log_aggregated_result_in_timer</a>(mean_scaled_timer, n_samples,</div>
<div class="line">                                                                              <span class="keyword">true</span>, N_SAMPLES_SCALE_CONVENIENCE);</div>
<div class="line">}</div>
<div class="ttc" id="aclassflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator_html_abd543abbfae859ddc111741468f95125"><div class="ttname"><a href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html#abd543abbfae859ddc111741468f95125">flow::perf::Checkpointing_timer::Aggregator::log_aggregated_result_in_timer</a></div><div class="ttdeci">static void log_aggregated_result_in_timer(log::Logger *logger_ptr, const Checkpointing_timer &amp;agg_timer, unsigned int n_samples, uint64_t mean_scale_or_zero=1)</div><div class="ttdoc">Given an aggregated-result Checkpointing_timer (as if returned by create_aggregated_result()) logs th...</div><div class="ttdef"><b>Definition:</b> checkpt_timer.cpp:471</div></div>
<div class="ttc" id="aclassflow_1_1perf_1_1Checkpointing__timer_html"><div class="ttname"><a href="classflow_1_1perf_1_1Checkpointing__timer.html">flow::perf::Checkpointing_timer</a></div><div class="ttdoc">The central class in the perf Flow module, this efficiently times the user's operation,...</div><div class="ttdef"><b>Definition:</b> checkpt_timer.hpp:188</div></div>
</div><!-- fragment --><p >This involves minimal overhead, as no timing calls occur at all until X is repeated a million times.</p>
<h3>Cross-product aggregation approach: Multiple <code><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a></code>s + <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html" title="This companion/inner class of Checkpointing_timer provides aggregation of results from many Checkpoin...">Checkpointing_timer::Aggregator</a></h3>
<p >If, by contrast, you want to divide X into checkpoints and see (say) how long checkpoint 3 takes on average (as well as the total as above), then use the dedicated <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html" title="This companion/inner class of Checkpointing_timer provides aggregation of results from many Checkpoin...">Checkpointing_timer::Aggregator</a> class for that purpose. This approach also allows one to do stuff (possibly unrelated stuff) between the many repetitions of operation X. Only X itself will be timed.</p>
<p >To use <code><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html" title="This companion/inner class of Checkpointing_timer provides aggregation of results from many Checkpoin...">Aggregator</a></code>, construct one; then simply create a <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a> for each repetition of X and time it as normal. Before or after each repetition, register it inside the agg using <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html#a18bdb2f17039bcb82ddd4022a3a8340d" title="Register given Checkpointing_timer for aggregated results.">Aggregator::aggregate()</a> which takes a pointer to <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a>. The only requirement is that the number and respective names of the checkpoints in each <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a> are the same for all of them.</p>
<p >Once enough samples (<code>n_samples</code> in earlier example) have been thus collected, <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html#a29c66da23a48bdb5096bf2f206f5cae4" title="Called after the final Checkpointing_timer has finished (final checkpoint() call) and been aggregate(...">Aggregator::log_aggregated_results()</a> will log every potential form (sum, mean, scaled-mean), not just for the total operation X but also each <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a>. For example, if X consists of steps X1, X2, X3, then one would see the mean duration of X1, X2, and X3 individually and their means would add up to the mean for all of X.</p>
<p >This is quite powerful; and while the overhead of creating individual <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a> objects, say, <em>might</em> affect the overall performance of the algorithm involving X, it shouldn't have any direct effect on the values actually being measured, since only each X invocation itself is measured; stuff in-between (slow or not) isn't. However:</p><ul>
<li><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html#a18bdb2f17039bcb82ddd4022a3a8340d" title="Register given Checkpointing_timer for aggregated results.">Checkpointing_timer::Aggregator::aggregate()</a> isn't thread-safe for concurrent access (so if that's relevant, you'll need a mutex lock around the call).</li>
<li>Always ensure you understand the structure of your measurement plan as it relates to concurrency. For example, it's meaningless to measure processor-time cost of X being done repeatedly, if various incarnations of X might be performed partially concurrently (say, if X = handling 1 HTTP request in a multi-threaded server under load). In that case processor-times will overlap and produce essentially meaningless (at the very least misleading) results. On the other hand, real-time measurements (<a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a8cbf506eda585c026dfb5b72c402d342" title="Measures real time (not processor time), using the highest-resolution system clock available that gua...">Clock_type::S_REAL_HI_RES</a>) make plenty of sense in that situation and would indeed reliably measure latency. Thread-time measurements (<a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a93867c73fb6ef991268c0052153344c2" title="Similar to S_CPU_TOTAL_HI_RES but applied to the calling thread as opposed to entire process.">Clock_type::S_CPU_THREAD_TOTAL_HI_RES</a>) can also make sense. Just saying: do not assume all clock types make sense in the face of concurrent operations; plan mindfully.</li>
</ul>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html" title="This companion/inner class of Checkpointing_timer provides aggregation of results from many Checkpoin...">Checkpointing_timer::Aggregator</a>. </dd></dl>
</div><h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="aa9940d8e87883f9985ba18939f833db9" name="aa9940d8e87883f9985ba18939f833db9"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aa9940d8e87883f9985ba18939f833db9">&#9670;&nbsp;</a></span>Checkpointing_timer() <span class="overload">[1/2]</span></h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">flow::perf::Checkpointing_timer::Checkpointing_timer </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">std::string &amp;&amp;&#160;</td>
          <td class="paramname"><em>name_moved</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601">Clock_types_subset</a>&#160;</td>
          <td class="paramname"><em>which_clocks</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>max_n_checkpoints</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">explicit</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Constructs a new timer and immediately begins measuring time, in that the next <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> call will record the time passed since right now. </p>
<p >Please read the following docs to achieve low overhead.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">name_moved</td><td>Nickname for the timer, for logging and such. If you want to preserve your string, pass in a copy: <code>string(your_name_value)</code>. </td></tr>
    <tr><td class="paramname">which_clocks</td><td>The clocks you want sampled in each <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a>. Please carefully read the doc headers of all <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a> <code>enum</code> members. </td></tr>
    <tr><td class="paramname">max_n_checkpoints</td><td>The number of times you shall call <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> shall not exceed this. A tight value saves RAM; but more importantly a <em>correct</em> upper bound guarantees no internal reallocation will occur in <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> which is important for maintaining low overhead. <code>assert()</code> trips if one breaks this promise. </td></tr>
    <tr><td class="paramname">logger_ptr</td><td>Logger to use for subsequently logging. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="a886e2150b2918df43c53d4850205e1c8" name="a886e2150b2918df43c53d4850205e1c8"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a886e2150b2918df43c53d4850205e1c8">&#9670;&nbsp;</a></span>Checkpointing_timer() <span class="overload">[2/2]</span></h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">flow::perf::Checkpointing_timer::Checkpointing_timer </td>
          <td>(</td>
          <td class="paramtype">const <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a> &amp;&#160;</td>
          <td class="paramname"><em>src</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">explicit</span><span class="mlabel">default</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Constructs a timer that is identical to but entirely independent of the source object. </p>
<p >When performed outside of performance-critical sections, this is very useful for data massaging <em>after</em> having completely measured something in a <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a>. E.g., one can create a copy and then <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a378be385d0c3dda261c8944551280010" title="Called anytime after the last checkpoint(), this modifies the data collected so far to be as if every...">scale()</a> it to obtain a mean, etc.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a> doc header for discussion of aggregation approaches.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">src</td><td>Object to copy. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="a9e6078df059d5626ab5774f0a33fbad7" name="a9e6078df059d5626ab5774f0a33fbad7"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9e6078df059d5626ab5774f0a33fbad7">&#9670;&nbsp;</a></span>checkpoint()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">const <a class="el" href="structflow_1_1perf_1_1Checkpointing__timer_1_1Checkpoint.html">Checkpointing_timer::Checkpoint</a> &amp; flow::perf::Checkpointing_timer::checkpoint </td>
          <td>(</td>
          <td class="paramtype">std::string &amp;&amp;&#160;</td>
          <td class="paramname"><em>name_moved</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Records a checkpoint, which takes a sample of all enabled <code>Clock_type</code>s' clocks and records the corresponding duration(s) since the last <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> or (if none) since construction. </p>
<p >In practice, at least one <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> call is required for <code>*this</code> to be of any use at all. The final <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> call's sample(s) determine the current value of <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#afeb1faa0e4962dacf9b6a134191a4933" title="Returns the duration(s) (for all enabled Clock_types) between construction and the last checkpoint() ...">since_start()</a> which is the duration of the entire operation, as measured since <code>*this</code> construction. Intermediate calls (ones preceding the final one) are optional and represent intermediate steps and how long they each took.</p>
<p ><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#afeb1faa0e4962dacf9b6a134191a4933" title="Returns the duration(s) (for all enabled Clock_types) between construction and the last checkpoint() ...">since_start()</a> depends on exactly two things: when <code>*this</code> was constructed, and when the last <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> call (at that time) was made.</p>
<h3>Naming vs. performance</h3>
<p ><code>name_moved</code> will be taken via move semantics, meaning no string buffer will be copied, only the pointer(s) and buffer size scalar(s) inside <code>std::string</code>. This helps performance. However, to <em>form</em> <code>name_moved</code> you will naturally spend some processor cycles which therefore risks slowing down the measured operation and polluting timing results. To avoid this, please follow the following suggestions.</p>
<ul>
<li>Passing a constant string as follows is very cheap: <code>"some constant"</code> or <code>string("same")</code>. So if that's good enough for you, do that.<ul>
<li>In most STL, due to the <code>std::string</code> SSO (optimization which stores a short-enough string directly inside the <code>string</code> object), if you keep the constant 15 characters or less in length, it's even cheaper; heap is not used as a result.</li>
</ul>
</li>
<li>Constructing something via <a class="el" href="namespaceflow_1_1util.html#a685b86585da2fa5186f51854e7ae1561" title="Equivalent to ostream_op_to_string() but returns a new string by value instead of writing to the call...">util::ostream_op_string()</a> (and/or <a class="el" href="classflow_1_1util_1_1String__ostream.html" title="Similar to ostringstream but allows fast read-only access directly into the std::string being written...">util::String_ostream</a>) adds about 500 nanoseconds per <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> call (e.g.: <code><a class="el" href="namespaceflow_1_1util.html#a685b86585da2fa5186f51854e7ae1561" title="Equivalent to ostream_op_to_string() but returns a new string by value instead of writing to the call...">util::ostream_op_string</a>("some string", some_int)</code>) on a 2015 MacBook Pro. For many, many timing scenarios such sub-microsecond overheads are no big deal, but watch out if you're measuring something tiny-subtle.<ul>
<li>If it is a problem, use a constant thing as in previous bullet. If that isn't sufficient, you can fairly easily use C-style direct-<code>char*</code>-writing to do it almost as quickly as that, or at least far closer to it than to the (syntactically-pretty but slow-in-*this*-context) stream-based string formation.</li>
</ul>
</li>
</ul>
<h3>Logging</h3>
<p >It will log a TRACE message. Hence if TRACE is enabled, timing results might be polluted, as logging can take non-trivial time.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">name_moved</td><td>Nickname for the timer, for logging and such. If you want to preserve your string, pass in a copy: <code>string(your_name_value)</code>. See above regarding perf impact. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Reference to immutable new <a class="el" href="structflow_1_1perf_1_1Checkpointing__timer_1_1Checkpoint.html" title="The entirety of the information recorded with each Checkpointing_timer::checkpoint() call; it contain...">Checkpoint</a> <code>struct</code>, as it sits directly inside <code>*this</code>. </dd></dl>

</div>
</div>
<a id="a1f03d654924a3724e1f051c119f3767b" name="a1f03d654924a3724e1f051c119f3767b"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a1f03d654924a3724e1f051c119f3767b">&#9670;&nbsp;</a></span>checkpoints()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">const std::vector&lt; <a class="el" href="structflow_1_1perf_1_1Checkpointing__timer_1_1Checkpoint.html">Checkpointing_timer::Checkpoint</a> &gt; &amp; flow::perf::Checkpointing_timer::checkpoints </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns the checkpoints recorded so far. </p>
<p >This returns a reference and thus avoids a copy. The reference is valid until <code>*this</code> destroyed.</p>
<dl class="section return"><dt>Returns</dt><dd>Checkpoints so far. </dd></dl>

</div>
</div>
<a id="a3b73f2812c2bf6a27ef2becc13859d73" name="a3b73f2812c2bf6a27ef2becc13859d73"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a3b73f2812c2bf6a27ef2becc13859d73">&#9670;&nbsp;</a></span>now() <span class="overload">[1/3]</span></h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="structflow_1_1perf_1_1Time__pt__set.html">Time_pt_set</a> flow::perf::Checkpointing_timer::now </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Sample all currently enabled <code>Clock_type</code>s' clocks and return those values, each of which is a time stamp relative to some Epoch value. </p>
<p >(The Epoch value differs by Clock_type. Durations can be generated by subtracting one time point from another which mathematically makes Epoch's meaning irrelevant.) The value <code><a class="el" href="namespaceflow_1_1perf.html#ace5f154155a7d9d5c112c1a83aa04fb5" title="Short-hand for a high-precision boost.chrono point in time, formally equivalent to flow::Fine_time_pt...">Time_pt()</a></code> (internally: 0 a/k/a Epoch) is set for the disabled clocks. In particular <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> will internally call this.</p>
<h3>Rationale</h3>
<p >It is unusual to use this directly by the user, as absolute time stamps aren't useful directly, while <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#afeb1faa0e4962dacf9b6a134191a4933" title="Returns the duration(s) (for all enabled Clock_types) between construction and the last checkpoint() ...">since_start()</a>, <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a1f03d654924a3724e1f051c119f3767b" title="Returns the checkpoints recorded so far.">checkpoints()</a>, the I/O facilities, etc., provide access to the various computed durations, so one needn't do the subtracting manually. Nevertheless being able to get the raw value is useful for (1) sanity-checking more advanced results; and (2) to time the timer! (An example of the latter is when I was comparing the duration of <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> with a constant <code>name_moved</code> vs. a dynamic-stream-created one vs. just getting the time stamp via <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a3b73f2812c2bf6a27ef2becc13859d73" title="Sample all currently enabled Clock_types&#39; clocks and return those values, each of which is a time sta...">now()</a> and not calling <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> at all.)</p>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<a id="a3138f716f6f5b3973a5ed53f68a3c332" name="a3138f716f6f5b3973a5ed53f68a3c332"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a3138f716f6f5b3973a5ed53f68a3c332">&#9670;&nbsp;</a></span>now() <span class="overload">[2/3]</span></h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1perf.html#ace5f154155a7d9d5c112c1a83aa04fb5">Time_pt</a> flow::perf::Checkpointing_timer::now </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">Clock_type</a>&#160;</td>
          <td class="paramname"><em>clock_type</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Based on the passed in <code>clock_type</code> argument, the current time is returned for that one particular clock type. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">clock_type</td><td>The type of clock to use. Please carefully read the doc headers of all <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a> <code>enum</code> members. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>The current time. </dd></dl>

</div>
</div>
<a id="a019df7b02e8aed1e86002c8a7b40dcf7" name="a019df7b02e8aed1e86002c8a7b40dcf7"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a019df7b02e8aed1e86002c8a7b40dcf7">&#9670;&nbsp;</a></span>now() <span class="overload">[3/3]</span></h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="structflow_1_1perf_1_1Time__pt__set.html">Time_pt_set</a> flow::perf::Checkpointing_timer::now </td>
          <td>(</td>
          <td class="paramtype">const <a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601">Clock_types_subset</a> &amp;&#160;</td>
          <td class="paramname"><em>which_clocks</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Based on the passed in <code>which_clocks</code> argument, the current time is returned for the clock types enabled by it. </p>
<p >Identical to non-<code>static</code> <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a3b73f2812c2bf6a27ef2becc13859d73" title="Sample all currently enabled Clock_types&#39; clocks and return those values, each of which is a time sta...">now()</a> but <code>which_clocks</code> is specified as arg instead of at construction.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">which_clocks</td><td>The types of clock to use. Please carefully read the doc headers of all <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a> <code>enum</code> members. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>The current time or times. </dd></dl>

</div>
</div>
<a id="a07204b9119b94bc10d53a8ba15c44797" name="a07204b9119b94bc10d53a8ba15c44797"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a07204b9119b94bc10d53a8ba15c44797">&#9670;&nbsp;</a></span>output()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void flow::perf::Checkpointing_timer::output </td>
          <td>(</td>
          <td class="paramtype">std::ostream *&#160;</td>
          <td class="paramname"><em>os</em></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Equivalent to <code>(*os) &lt;&lt; (*this)</code>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">os</td><td>Pointer to <code>ostream</code> to which to write. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="a32ed9864d46708789d7418ab637ff382" name="a32ed9864d46708789d7418ab637ff382"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a32ed9864d46708789d7418ab637ff382">&#9670;&nbsp;</a></span>process_cpu_clock_types()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601">Clock_types_subset</a> flow::perf::Checkpointing_timer::process_cpu_clock_types </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Returns the bit-set containing only those <code>Clock_type</code>s enabled that measure passage of processor time by all threads of the calling process combined. </p>
<h3>Rationale</h3>
<p >See <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a959a0446aa6a0b6db59e9892d8f0a699" title="Returns the bit-set containing only those Clock_types enabled that measure passage of real (wall cloc...">real_clock_types()</a>.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a> </dd></dl>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<a id="a959a0446aa6a0b6db59e9892d8f0a699" name="a959a0446aa6a0b6db59e9892d8f0a699"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a959a0446aa6a0b6db59e9892d8f0a699">&#9670;&nbsp;</a></span>real_clock_types()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601">Clock_types_subset</a> flow::perf::Checkpointing_timer::real_clock_types </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Returns the bit-set containing only those <code>Clock_type</code>s enabled that measure passage of real (wall clock) time. </p>
<h3>Rationale</h3>
<p >One application is when deciding on the constructor <code>which_clocks</code> arg (also a <code>Clock_types_subset</code>). If one wants to time some operation in such a way as to make only real-time clocks make sense, and the user is allowed to control which clock types to sample, then one can do:</p>
<div class="fragment"><div class="line"><span class="comment">// They can specify a bitmask the_clock_set_from_config; then we potentially cull that further to exclude all</span></div>
<div class="line"><span class="comment">// but the real-time clocks, because we feel only those make sense in our timing context.</span></div>
<div class="line"><span class="keyword">const</span> <span class="keyword">auto</span> which_clocks = <a class="code hl_function" href="classflow_1_1perf_1_1Checkpointing__timer.html#a959a0446aa6a0b6db59e9892d8f0a699">Checkpointing_timer::real_clock_types</a>() &amp; the_clock_set_from_config;</div>
<div class="line"><a class="code hl_class" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a> timer(..., which_clocks, ...);</div>
<div class="line"><span class="comment">// The timing has begun....</span></div>
<div class="ttc" id="aclassflow_1_1perf_1_1Checkpointing__timer_html_a959a0446aa6a0b6db59e9892d8f0a699"><div class="ttname"><a href="classflow_1_1perf_1_1Checkpointing__timer.html#a959a0446aa6a0b6db59e9892d8f0a699">flow::perf::Checkpointing_timer::real_clock_types</a></div><div class="ttdeci">static Clock_types_subset real_clock_types()</div><div class="ttdoc">Returns the bit-set containing only those Clock_types enabled that measure passage of real (wall cloc...</div><div class="ttdef"><b>Definition:</b> checkpt_timer.cpp:77</div></div>
</div><!-- fragment --><dl class="section see"><dt>See also</dt><dd><a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a></dd></dl>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<a id="a378be385d0c3dda261c8944551280010" name="a378be385d0c3dda261c8944551280010"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a378be385d0c3dda261c8944551280010">&#9670;&nbsp;</a></span>scale()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void flow::perf::Checkpointing_timer::scale </td>
          <td>(</td>
          <td class="paramtype">uint64_t&#160;</td>
          <td class="paramname"><em>mult_scale</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">uint64_t&#160;</td>
          <td class="paramname"><em>div_scale</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Called anytime after the last <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a>, this modifies the data collected so far to be as if every checkpoint duration D shortened/lengthened by <code>mult_scale</code> and divided by <code>div_scale</code>. </p>
<p >For example, if <code>float(mult_scale) / float(div_scale) == 0.5</code>, and 3 checkpoints were recorded as (6s, 4s, 12s) (<code><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#afeb1faa0e4962dacf9b6a134191a4933" title="Returns the duration(s) (for all enabled Clock_types) between construction and the last checkpoint() ...">since_start()</a></code> = 12s + 4s + 6s = 22s), then after the <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a378be385d0c3dda261c8944551280010" title="Called anytime after the last checkpoint(), this modifies the data collected so far to be as if every...">scale()</a> call the checkpoints will reflect (3s, 2s, 6s) (<code><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#afeb1faa0e4962dacf9b6a134191a4933" title="Returns the duration(s) (for all enabled Clock_types) between construction and the last checkpoint() ...">since_start()</a></code> == 11s).</p>
<p >In particular (and the original use case for this &ndash; see doc header), if one recorded operation X repeated sequentially 100x, with <code>*this</code> constructed just before the first iteration and <code><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a></code>ed just after the 100th, then performing <code>scale(1, 100)</code> would effectively result in <code>*this</code> representing the mean duration of a single X iteration.</p>
<p >Formally, behavior is undefined if one calls <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> after calling <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a378be385d0c3dda261c8944551280010" title="Called anytime after the last checkpoint(), this modifies the data collected so far to be as if every...">scale()</a>. Informally it is likely to result in nonsensical data for all checkpoints created starting with that one and for <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#afeb1faa0e4962dacf9b6a134191a4933" title="Returns the duration(s) (for all enabled Clock_types) between construction and the last checkpoint() ...">since_start()</a>.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">mult_scale</td><td>The timer data are conceptually multiplied by this, first. </td></tr>
    <tr><td class="paramname">div_scale</td><td>The timer data are conceptually divided by this, next. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="afeb1faa0e4962dacf9b6a134191a4933" name="afeb1faa0e4962dacf9b6a134191a4933"></a>
<h2 class="memtitle"><span class="permalink"><a href="#afeb1faa0e4962dacf9b6a134191a4933">&#9670;&nbsp;</a></span>since_start()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> flow::perf::Checkpointing_timer::since_start </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns the duration(s) (for all enabled <code>Clock_type</code>s) between construction and the last <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> call. </p>
<p >Behavior is undefined if <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">checkpoint()</a> has not been called.</p>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<a id="aabebe01d0d5096618a8a7c2cf52320fb" name="aabebe01d0d5096618a8a7c2cf52320fb"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aabebe01d0d5096618a8a7c2cf52320fb">&#9670;&nbsp;</a></span>thread_cpu_clock_types()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601">Clock_types_subset</a> flow::perf::Checkpointing_timer::thread_cpu_clock_types </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Returns the bit-set containing only those <code>Clock_type</code>s enabled that measure passage of processor time by the calling thread. </p>
<h3>Rationale</h3>
<p >See <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a959a0446aa6a0b6db59e9892d8f0a699" title="Returns the bit-set containing only those Clock_types enabled that measure passage of real (wall cloc...">real_clock_types()</a>.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a> </dd></dl>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<h2 class="groupheader">Friends And Related Function Documentation</h2>
<a id="a6d5b7cbbe0ec5133299f97148ef3eaa0" name="a6d5b7cbbe0ec5133299f97148ef3eaa0"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a6d5b7cbbe0ec5133299f97148ef3eaa0">&#9670;&nbsp;</a></span>operator&lt;&lt;()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">std::ostream &amp; operator&lt;&lt; </td>
          <td>(</td>
          <td class="paramtype">std::ostream &amp;&#160;</td>
          <td class="paramname"><em>os</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a> &amp;&#160;</td>
          <td class="paramname"><em>timer</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">related</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Prints string representation of the given <code><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a></code> (whether with original data or an aggregated-result timer) to the given <code>ostream</code>. </p>
<p >Note this is multi-line output that does <em>not</em> end in newline.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">os</td><td>Stream to which to write. </td></tr>
    <tr><td class="paramname">timer</td><td>Object to serialize. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>os</code>. </dd></dl>

</div>
</div>
<hr/>The documentation for this class was generated from the following files:<ul>
<li>perf/<a class="el" href="checkpt__timer_8hpp.html">checkpt_timer.hpp</a></li>
<li>perf/<a class="el" href="checkpt__timer_8cpp.html">checkpt_timer.cpp</a></li>
<li>perf/<a class="el" href="perf__fwd_8hpp.html">perf_fwd.hpp</a></li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Mar 28 2025 22:55:32 for Flow by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
